#pragma once
//#include "stdafx.h"
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;

typedef unsigned int uint;
typedef vector<uint> vec;

class large
{
public:
    large (const char *str);
    large(int i);
    large(uint i=0);
    large(long i);
    large operator-()const;
    large &operator+=(const large &y);
    large &operator-=(const large &y);
    large &operator*=(int y);
    large &operator*=(uint y);
    large &operator*=(large y);
    large &operator/=(const large &divisor);
    large &operator%=(const large &divisor);
    large &operator <<= (uint k);
    large &operator >>= (uint k);
    void divide(large denom, large &quot, large &rem, bool RemDesired)const;
    // ??????? num2char ??????????? ?????? ? ?????? large
    //? ??? ?????????? ????????????? s ? ???????? ???????:
    void num2char(vector<char> &s) const;
    int compare(const large &y)const;
private:
    vec P;
    bool neg;
    void SetLen(int n);
    void reduce();
    void DDproduct(uint A, uint B, uint &Hi, uint &Lo)const;
    uint DDquotient(uint A, uint B, uint d)const;
    void subtractmul(uint *a, uint *b, int n, uint &q)const;
    bool normalize(large &denom, large &num,int &x)const;
    void unnormalize(large &rem, int x, bool SecondDone)const;
};

large operator+(large x, const large &y);
large operator-(large x, const large &y);
large operator*(large x, const large &y);
large operator/(large x, const large &y);
large operator%(large x, const large &y);
large operator<<(large u, uint k);
large operator>>(large u, uint k);
ostream &operator<<(ostream &os, const large &x);
istream &operator>>(istream &os, large &x) ;
bool operator==(const large &x, const large &y);
bool operator<(const large &x, const large &y);
bool operator!=(const large &x, const large &y);
bool operator>(const large &x, const large &y);
large abs(large x);
large sqrt(const large &a);
large power(large x, uint n) ;


#if (defined(_MSC_VER) && !defined(_SGI_MSVC)) 

namespace flinn
{
    template <class T>
    inline const T& min(const T& a, const T& b)
    {
        return a < b ? a : b;
    }

    template <class T>
    inline const T& max(const T& a, const T& b)
    {
        return a < b ? b : a;
    }
}

#endif 
